#ifndef DEVICE_H
#define DEVICE_H

#include "global.h"
#include "freq_table.h"
#include "z_action.h"
#include "xy_action.h"
#include "wwdg.h"

//------------------------------------------------------------------------------
// IO map
//------------------------------------------------------------------------------

// 步进电机STEP脉冲信号由定时器PWM输出产生：
// X电机STEP: PB8  (TIMER3_CH2)
// Y电机STEP: PA8  (TIMER0_CH0) 
// Z电机STEP: PA6  (TIMER2_CH0)
// M电机STEP: PA1  (TIMER1_CH1)
#define IO_X_DIR(n)      (!n)?gpio_bit_write(GPIOB,GPIO_PIN_5,SET):gpio_bit_write(GPIOB,GPIO_PIN_5,RESET) // X电机方向
#define IO_Y_DIR(n)      (!n)?gpio_bit_write(GPIOB,GPIO_PIN_1,SET):gpio_bit_write(GPIOB,GPIO_PIN_1,RESET) // Y电机方向
#define IO_Z_DIR(n)      (!n)?gpio_bit_write(GPIOA,GPIO_PIN_4,SET):gpio_bit_write(GPIOA,GPIO_PIN_4,RESET) // Z电机方向
#define IO_M_DIR(n)      (!n)?gpio_bit_write(GPIOC,GPIO_PIN_15,SET):gpio_bit_write(GPIOC,GPIO_PIN_15,RESET) // 混匀电机方向

#define IO_X_EN(n)       (!n)?gpio_bit_write(GPIOB,GPIO_PIN_9,SET):gpio_bit_write(GPIOB,GPIO_PIN_9,RESET)   // X电机使能    原M电机 PB9
#define IO_Y_EN(n)       (!n)?gpio_bit_write(GPIOB,GPIO_PIN_10,SET):gpio_bit_write(GPIOB,GPIO_PIN_10,RESET) // Y电机使能    PB10
#define IO_Z_EN(n)       (!n)?gpio_bit_write(GPIOB,GPIO_PIN_0,SET):gpio_bit_write(GPIOB,GPIO_PIN_0,RESET)   // Z电机使能    PB0
#define IO_M_EN(n)       (!n)?gpio_bit_write(GPIOA,GPIO_PIN_3,SET):gpio_bit_write(GPIOA,GPIO_PIN_3,RESET)   // 混匀电机使能  PA3

#define X_AT_HOME     (!gpio_input_bit_get(GPIOB,GPIO_PIN_4))  // X原点传感器
#define Y_AT_HOME     (!gpio_input_bit_get(GPIOC,GPIO_PIN_14)) // Y左原点传感器
#define Z_AT_HOME     (!gpio_input_bit_get(GPIOA,GPIO_PIN_15)) // Z原点传感器
#define M_AT_HOME     (!gpio_input_bit_get(GPIOC,GPIO_PIN_13)) // M原点传感器

#define IO_X_LOCK(n)   (n)?gpio_bit_write(GPIOB,GPIO_PIN_6,SET):gpio_bit_write(GPIOB,GPIO_PIN_6,RESET) // X电机锁存
#define IO_Y_LOCK(n)   (n)?gpio_bit_write(GPIOB,GPIO_PIN_2,SET):gpio_bit_write(GPIOB,GPIO_PIN_2,RESET) // Y电机锁存
#define IO_Z_LOCK(n)   (n)?gpio_bit_write(GPIOA,GPIO_PIN_5,SET):gpio_bit_write(GPIOA,GPIO_PIN_5,RESET) // Z电机锁存
#define IO_M_LOCK(n)   (n)?gpio_bit_write(GPIOA,GPIO_PIN_0,SET):gpio_bit_write(GPIOA,GPIO_PIN_0,RESET) // M电机锁存

#define X_DIR_OUTPUT(dir)   (!(dir))                        // X方向位输出
#define Y_DIR_OUTPUT(dir)   (!(dir))                        // Y方向位输出
#define Z_DIR_OUTPUT(dir)   (!(dir))                        // Z方向位输出
#define M_DIR_OUTPUT(dir)   (!(dir))                        // M方向位输出

#define ZHOD          (!gpio_input_bit_get(GPIOB,GPIO_PIN_3))  // Z抓杯传感器
#define ZLIM          (!gpio_input_bit_get(GPIOB,GPIO_PIN_15)) // Z抓杯到位传感器

#define SET_Z_MOTOR_EXCITATION(n)   do{Z_MOTOR_PORT &= ~Z_MOTOR_MASK; Z_MOTOR_PORT |= (n);}while(0)

#define IO_PICK_CUP          ZLIM
#define IO_HOLDING_CUP       ZHOD

//------------------------------------------------------------------------------

// server_status定义
enum STATUS_CODE
{
    STATUS_IDLE = 0,
    STATUS_BUSY = 0xFFFF
};


// 电机碰到原点后运行的步数
#define Y_RESET_BUFFER_STEP     (MICROSTEP * 5)     // Y电机复位时, 经过原点后继续运行的步数
#define Y_LIMIT_BUFFER_STEP     (long)(Y_LIMIT_DISTANCE * SPR / Y_PERIMETER)// Y电机复位时, 经过原点后继续运行的步数
#define Z_RESET_BUFFER_STEP     (MICROSTEP * 5)     // Z电机复位时, 经过原点后继续运行的步数
#define Z_PROBE_BUFFER_STEP     200                 // z抓杯感应到信号时继续下探的步数
#define Z_RELEASE_BUFFER_STEP   200                 // z放杯感应到信号时继续下探的步数
// 抓杯时, 检测到抓杯信号后回退的步数
#define PICK_CUP_ROLLBACK_STEP  (long)(PICK_CUP_ROLLBACK * SPR / Z_PERIMETER)


#define Y_MAX_RESET_SPEED       4000

// Y移动一个定位销距离步数
#define Y_STEPS_BY_ONE_HOLE     (SPR * LOCATION_PERIMETER / Y_PERIMETER)

// 放杯到位检测传感器生效掩码
#define RELEASE_CUP_SENSOR_MASK     0x01UL

void Device_Init(void);

// 系统时钟
#define US_TO_TICK_UL(us)       (us)    // 将us时间转换为定时器计数值, 最大32.767ms
#define US_TO_TICK(us)          (us)
#define MS_TO_TICK_HIGH(ms)     ((ushort)(US_TO_TICK_UL((ms) * 1e3)/65536))
#define ONE_MS                  US_TO_TICK(1000)        // 1ms
#define TWO_MS                  US_TO_TICK(2000)        // 2ms
#define TEN_MS                  US_TO_TICK(10000)       // 10ms
#define _15_MS                  US_TO_TICK(15000)       // 15ms
// #define TICK_TO_US(tick)        ((ulong)((tick)*(12e6/SYSCLK)))

ushort SystemTickLow(void);                         // 系统时钟低16位, X0.5us
ushort SystemTickHigh(void);                        // 系统时钟高16位, X32.768ms
ulong SystemTick(void);                             // 系统时钟, X0.5us
void Delay_Tick(ushort tick);
void Delay_Tick_Event(ulong tick);
#define Delay_us(n)                 Delay_Tick(US_TO_TICK(n))

extern uchar server_address;       // 设备地址
extern bit pending_action;
extern bit astar_map_changed;           // 地图数据已经改变, 需要重新建立

void Update_IO(void);
void Update_Ref_Speed(void);
void Main_Loop(void);
void Process_Main_Loop(void);
void Process_Action(void);

void test_fuction(void);

#endif // DEVICE_H
